home *** CD-ROM | disk | FTP | other *** search
- /*
- File: SEUtils.cpp
-
- Contains: xxx put contents here xxx
-
- Owned by: Jon Pugh
-
- Copyright: © 1996 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <6> 12/13/96 JP 1611571: Renamed parameter
- <5> 9/27/96 TJ Added Includes
- <4> 9/26/96 JP 1372897: Added CompareDescs utility.
- <3> 9/24/96 TJ Added Includes
- <2> 9/23/96 JP 1384958: Moved routines from SEPriv.cpp,
- renamed GetDefaultRootFrame & added
- ShouldHandleEvent
-
- To Do:
- */
-
- /*
- File: SEUtils.cpp
-
- Contains: Semantic Event Utility Functions implementation.
-
- Owned by: Nick Pilch
-
- Copyright: © 1993 - 1995 by Apple Computer, Inc., all rights reserved.
-
-
-
- */
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef _ODDESUTL_
- #include <ODDesUtl.h>
- #endif
-
- #ifndef SOM_ODFrame_xh
- #include <Frame.xh>
- #endif
-
- #ifndef _ODDEBUG_
- #include "ODDebug.h"
- #endif
-
- #ifndef SOM_ODAppleEvent_xh
- #include "ODAplEvt.xh"
- #endif
-
- #ifndef SOM_ODOSLToken_xh
- #include "ODOSLTkn.xh"
- #endif
-
- #ifndef SOM_ODNameResolver_xh
- #include "NamRslvr.xh"
- #endif
-
- #ifndef __FILES__
- #include <Files.h>
- #endif
-
- #ifndef _EXCEPT_
- #include "Except.h"
- #endif
-
- #ifndef _ODMEMORY_
- #include "ODMemory.h"
- #endif
-
- #ifndef __STRING__
- #include <string.h>
- #endif
-
- #ifndef __STDLIB__
- #include <stdlib.h>
- #endif
-
- #ifndef __QUICKDRAW__
- #include <Quickdraw.h>
- #endif
-
- #ifndef __AEOBJECTS__
- #include <AEObjects.h>
- #endif
-
- #pragma segment ODSEUtils
-
- #ifndef _SEUTILS_
- #include "SEUtils.h"
- #endif
-
- #ifndef SOM_ODSession_xh
- #include "ODSessn.xh"
- #endif
-
- #ifndef SOM_ODWindowState_xh
- #include <WinStat.xh>
- #endif
-
- #ifndef SOM_ODWindow_xh
- #include <Window.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_ODRegistry_defined
- #include "ODRgstry.xh"
- #endif
-
- #ifndef _SIHLPABS_
- #include "SIHlpAbs.h"
- #endif
-
- #ifndef _TEMPITER_
- #include "TempIter.h"
- #endif
-
- #ifndef SOM_ODEmbeddedFramesIterator_xh
- #include "EmbFrItr.xh"
- #endif
-
- #ifndef _ODUTILS_
- #include <ODUtils.h>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdDefs_defined
- #include <StdDefs.xh>
- #endif
-
- #ifndef SOM_ODObjectSpec_xh
- #include "ODObjSpc.xh"
- #endif
-
- #ifndef __ASREGISTRY__
- #include <ASRegistry.h>
- #endif
-
- #ifndef __TEXTUTILS__
- #include <TextUtils.h>
- #endif
-
- OSErr MyAECoerceDescPtr(AEDesc theAEDesc, DescType toType, Ptr dataPtr,
- Size maximumSize, Size* actualSize);
- long MyRandom(long count);
-
- ODBoolean MissingParams(const AppleEvent* message)
- {
- AEKeyword missedKeyword;
- DescType ignoreType;
- Size ignoreSize;
- OSErr myErr;
-
- myErr = AEGetAttributePtr(message, keyMissedKeywordAttr, typeWildCard,
- &ignoreType, (Ptr)&missedKeyword,
- sizeof(missedKeyword), &ignoreSize);
- return myErr == noErr;
- }
-
- /* -- I've made this a memeber function of ODApplicatiin (in Shell.cp)
- // HEY! This function assumes that typeCode is typeChar and toType is typeFSS.
- //pascal OSErr Pathname2FSSpec(DescType typeCode,
- // Ptr dataPtr,
- // Size dataSize,
- // DescType toType,
- // long handlerRefCon,
- // AEDesc* result)
-
-
- // ODDescCoercionHandler
- void Pathname2FSSpec( ODPart* thePart, DescType typeCode, Ptr dataPtr,
- Size dataSize, DescType toType, long handlerRefCon,
- AEDesc* result)
- {
- Str255 fileName;
- FSSpec fileSpec;
- const short kNoVRefNum = 0;
- const long kNoDirID = 0;
- OSErr error;
-
- if (dataSize > sizeof(Str255))
- return bdNamErr;
-
- ODBlockMove(dataPtr, fileName + 1, dataSize);
- fileName[0] = (unsigned char)dataSize;
-
- error = FSMakeFSSpec(kNoVRefNum, kNoDirID, fileName, &fileSpec);
- THROW_IF_ERROR( error );
-
- error = AECreateDesc(typeFSS, (Ptr) &fileSpec, sizeof(fileSpec), result);
- THROW_IF_ERROR( error );
- }
-
- */
-
- /*
- The following functions were lifted from Quill.p and translated
- */
-
- #define genericErr (-1799)
- #define errAEBadData (-15310)
- Size gActSize;
-
-
- OSErr DecodeOrdinal(AEDesc ordData, long count, long* index,
- Boolean* allFlag, Boolean* zeroFlag)
- /* this routine is used whenever an element is specified by an absolute position
- within a sequence of elements - such as "word 3 of window 'johnson'", "any line
- of item 17 of window 'Kelvin'", etc. The data specifying the position can be
- a positive integer (which just means the actual position of the element in the
- sequence: 1 for the first element, 2 for the second, etc.), a negative integer
- (which indicates position relative to the last element of the sequence: -1 is
- the last element, -2 the next to last, etc.), or a descriptor of typeAbsoluteOrdinal:
- kAEFirst, kAELast, kAEMiddle, kAEAny, or kAEAll.
-
- DecodeOrdinal takes the data specifying the position, and a count of all the elements
- in the sequence under consideration, and returns (whenever possible) a positive integer
- (in the return VAR index) representing the actual position of the element in the sequence
- (1 for first, 2 for second, etc.). It also returns flags indicating (a) whether the
- ordinal was kAEAll and (b) whether the count was 0; both of these are conditions that
- many calling routines will have to special-case. In the case of kAEAll, the return VAR
- index is set to the count; in the case of count = 0, the return VAR index is set to 0.
-
- There are a few error conditions: (a) count < 0; (b) bad ordData (not an integer, and
- not one of the five defined absolute ordinal specifiers). **CHECK - should "integer ordData
- out of range" (for example, an integer > count, or < -count, or = 0) be an error,
- or should we allow that so that people can talk about "the hypothetical element
- beyond the last", or whatever? For now, let's make that a non-error.
-
- INPUTS: ordData a descriptor that specifies an ordinal - either
- an integer (positive or negative) or something
- of typeAbsoluteOrdinal
- count the total number of elements in the group involved
- (number of windows, number or chars, or whatever)
- index return VAR for the actual position being described
- allFlag return VAR: TRUE if the ordData was kAEAll, FALSE o.w.
- zeroFlag return VAR: TRUE if the count was zero (for many
- calling routines this is an error condition), FALSE o.w.
- OUTPUTS: error code (noErr if none)
- */
- {
- OSErr myErr;
- DescType absOrd;
- long intOrd;
-
- myErr = genericErr;
- *index = count;
- *allFlag = kODFalse;
-
- *zeroFlag = (count == 0);
- if (count < 0)
- {
- myErr = errAEBadData;
- goto exit;
- }
-
- myErr = MyAECoerceDescPtr(ordData, typeAbsoluteOrdinal, (Ptr)&absOrd,
- sizeof(absOrd), &gActSize);
- if (myErr == noErr)
- {
- /* got an absolute ordinal */
- /* note that, as we enter here, index == count and myErr == noErr */
- *allFlag = (absOrd == kAEAll);
- if (*allFlag)
- goto exit; /* finish up */
-
- if ((absOrd != kAEFirst) && (absOrd != kAELast)
- && (absOrd != kAEMiddle) && (absOrd != kAEAny))
- {
- myErr = errAEBadData;
- goto exit;
- }
-
- if (*zeroFlag || (absOrd == kAELast))
- goto exit; /* in both cases, index == count (already done) */
-
- if (absOrd == kAEFirst)
- *index = 1;
- else if (absOrd == kAEMiddle)
- *index = (count + 1) / 2;
- else
- *index = MyRandom(count);
-
- goto exit;
- } /* of absolute ordinal */
-
- /* try actual integer */
- myErr = MyAECoerceDescPtr(ordData, typeLongInteger, (Ptr)&intOrd,
- sizeof(intOrd), &gActSize);
- if (myErr)
- goto exit;
-
- if (intOrd < 0)
- *index = count + intOrd + 1; /* e.g., intOrd == -1 means index == count */
- else
- *index = intOrd;
-
- /* should we validate index here (wrt count)? let's skip it for now */
-
- exit: /* finish up */
- return myErr;
- }
-
- OSErr MyAECoerceDescPtr(AEDesc theAEDesc, DescType toType, Ptr dataPtr,
- Size maximumSize, Size* actualSize)
- /* this routine plugs a hole that's been nagging at me in the AppleEvents
- interface. It takes a descriptor and coerces it to a desired type; but
- instead of returning a descriptor, it returns data in a buffer specified
- by the caller.
- INPUTS: theAEDesc descriptor to be coerced
- toType type to coerce it to
- dataPtr ptr to data buffer
- maximumSize maximum length in bytes of data to be returned
- actualSize actual length in bytes of data for the descriptor
- OUTPUTS: error code (noErr if none)
- ERRORS:
- SIDE EFFECTS:
- NOTES: 12/16/91 BHM (1) Changed to avoid unecessary duplication when the type
- doesn't really change (this should also enable it to handle
- typeWildCard better)
- (2) We don't need to dispose of newDesc because it is a direct
- copy (not a duplicate) of either theAEDesc or resultDesc - that
- is, it contains the same handle
- 03/12/92 BHM Added special case to deal with NIL data handles (which should only
- occur for typeNull, I believe)
- */
- {
- short myErr;
- AEDesc newDesc;
- AEDesc resultDesc = NULL_DESCRIPTOR_DEFINITION;
- Size transferSize;
-
- myErr = errAECoercionFail;
-
- /* to avoid unnecessary duplication, check old type vs. new type */
- if ((theAEDesc.descriptorType == toType) || (toType == typeWildCard))
- newDesc = theAEDesc;
- else
- {
- /* must coerce to new type */
- myErr = AECoerceDesc(&theAEDesc, toType, &resultDesc);
- if (myErr)
- goto exit;
- newDesc = resultDesc;
- }
-
- // WITH newDesc DO
- {
- /* special-case for NIL handle */ /* should I **CHECK to make sure it's typeNull here? */
- if (newDesc.dataHandle == kODNULL)
- {
- actualSize = 0;
- myErr = noErr;
- goto exit;
- }
-
- /* not NIL handle - get the size */
- *actualSize = ODGetHandleSize((ODHandle)newDesc.dataHandle);
- myErr = MemError();
- if (myErr)
- goto exit;
-
- /* calculate number of bytes to move */
- transferSize = *actualSize;
- if (maximumSize < transferSize)
- transferSize = maximumSize;
-
- /* move the data */
- // HLock(newDesc.dataHandle);
- ODBlockMove(*(newDesc.dataHandle), dataPtr, transferSize);
- // HUnlock(newDesc.dataHandle);
- } /* of WITH newDesc */
-
- /* everything fine */
- myErr = noErr;
-
- exit: /* finish up */
- AEDisposeDesc(&resultDesc);
- return myErr;
- } /* MyAECoerceDescPtr */
-
- long MyRandom(long count)
- /* return a random integer between 1 and count, inclusive
- INPUTS: count upper bound for random number
- OUTPUTS: a random integer between 1 and count, inclusive
- NOTES: **CHECK - this is a quick, dirty, and WRONG version
- to be used for testing only
- */
- {
- long longRandom;
-
- longRandom = 0x10000*Random() + Random();
- return (labs(longRandom) % count) + 1;
- } /* MyRandom */
-
- //------------------------------------------------------------------------------
- // GetSLongAttr
- //------------------------------------------------------------------------------
-
- ODSLong GetSLongAttr(AppleEvent* ae, AEKeyword keyword)
- {
- OSErr result;
- ODSLong value;
- DescType actualType;
- Size sizeOfBuffer = sizeof(value);
- Size actualSize;
-
- result = AEGetAttributePtr(ae, keyword, typeWildCard, &actualType,
- (Ptr)&value, sizeOfBuffer, &actualSize);
- if (result != noErr)
- THROW((ODError)result);
- //if ((actualType != typeShortInteger) || (actualSize != sizeOfBuffer))
- if (actualSize != sizeOfBuffer)
- THROW(kODErrOutOfMemory);
-
- return value;
- }
-
- //------------------------------------------------------------------------------
- // GetSLongAttrOD
- //------------------------------------------------------------------------------
-
- ODSLong GetSLongAttrOD(ODAppleEvent* ae, AEKeyword keyword)
- {
- AppleEvent realAE;
- THROW_IF_ERROR( ODDescToAEDesc( ae, &realAE ) ) ;
- ODSLong result = GetSLongAttr( &realAE, keyword );
- (void)AEDisposeDesc( &realAE );
- return result;
- }
-
- //------------------------------------------------------------------------------
- // ThrowIfCantCoerce
- //------------------------------------------------------------------------------
-
- // does an in-place coercion!
- void ThrowIfCantCoerce( AEDesc* data, DescType desiredType )
- {
- if ( data->descriptorType == desiredType )
- return ;
-
- AEDesc newDesc ;
- THROW_IF_ERROR( AECoerceDesc( data, desiredType, &newDesc ) ) ;
- AEDisposeDesc( data ) ;
- *data = newDesc ;
- }
-
- //------------------------------------------------------------------------------
- // ThrowIfNotAbsent
- //------------------------------------------------------------------------------
-
- void ThrowIfNotAbsent( OSErr err )
- {
- if ( (err == noErr) || ( err == errAEDescNotFound ) )
- return ;
- THROW( err ) ;
- }
-
- //------------------------------------------------------------------------------
- // UpdateUserToken
- //------------------------------------------------------------------------------
-
- void UpdateUserToken(Environment* ev, ODNameResolver* resolver,
- ODOSLToken* odToken, AEDesc* desc)
- {
- ODDesc* userODToken = resolver->GetUserToken(ev, odToken);
- THROW_IF_ERROR(AEDescToODDesc(desc, userODToken));
- THROW_IF_ERROR(AEDisposeDesc(desc));
- }
-
- //------------------------------------------------------------------------------
- // CountEmbeddedParts
- //------------------------------------------------------------------------------
-
- ODSLong CountEmbeddedParts(Environment* ev, ODPart* prt)
- {
- if ( prt == kODAppShell ) return 1;
-
- ODSLong result = 0;
- for ( TempODEmbeddedFramesIterator iter(ev,prt,kODNULL);
- iter.Current(); iter.Next() )
- {
- ++result;
- }
- return result;
- }
-
- //------------------------------------------------------------------------------
- // ODDisposeAppleEvent
- //------------------------------------------------------------------------------
-
- OSErr ODDisposeAppleEvent( AppleEvent* aevt )
- {
- (void)AEDisposeDesc( aevt );
- return AEDisposeDesc( aevt );
- }
-
-
- //------------------------------------------------------------------------------
- // FrameFromStandardPartToken
- //------------------------------------------------------------------------------
-
- ODFrame* FrameFromStandardPartToken(AEDesc* token)
- {
- ODFrame* frame;
- PartFrameFromStandardPartToken( token, kODNULL, &frame );
- return frame;
- }
-
- //------------------------------------------------------------------------------
- // PartFromStandardPartToken
- //------------------------------------------------------------------------------
-
- ODPart* PartFromStandardPartToken(AEDesc* token)
- {
- ODPart* part;
- PartFrameFromStandardPartToken( token, &part, kODNULL );
- return part;
- }
-
- //------------------------------------------------------------------------------
- // PartFrameFromStandardPartToken
- //------------------------------------------------------------------------------
-
- void PartFrameFromStandardPartToken(AEDesc* token, ODPart** part,
- ODFrame** frame)
- {
- ODBoolean coerced = kODFalse;
- if ( token->descriptorType != kODStandardPartTokenType ) // dup. only if must
- {
- AEDesc coercedToken;
- THROW_IF_ERROR( AECoerceDesc( token, kODStandardPartTokenType,
- &coercedToken ) );
- coerced = kODTrue;
- token = &coercedToken;
- }
- WASSERT(token->descriptorType == kODStandardPartTokenType);
- WASSERT(token->dataHandle != kODNULL);
- WASSERT( GetHandleSize(token->dataHandle) == sizeof(StandardPartToken) );
- StandardPartToken spt = FIRSTBYTESFROMHANDLE(
- token->dataHandle, StandardPartToken );
- if ( part )
- *part = spt.fPart;
- if ( frame )
- *frame = spt.fFrame;
- if ( coerced )
- (void)AEDisposeDesc( token );
- }
-
- //------------------------------------------------------------------------------
- // CanBeStandardPartToken
- //------------------------------------------------------------------------------
-
- ODBoolean CanBeStandardPartToken( AEDesc* token )
- {
- ODBoolean result = (token->descriptorType == kODStandardPartTokenType) &&
- (GetHandleSize(token->dataHandle) == sizeof(StandardPartToken));
- if ( !result )
- {
- AEDesc coercedToken;
- OSErr err = AECoerceDesc( token, kODStandardPartTokenType,
- &coercedToken );
- result = (err == noErr) &&
- (coercedToken.descriptorType == kODStandardPartTokenType) &&
- (GetHandleSize(coercedToken.dataHandle)
- == sizeof(StandardPartToken));
- (void)AEDisposeDesc( &coercedToken );
- }
- return result;
- }
-
- //------------------------------------------------------------------------------
- // CreateStandardPartToken
- //------------------------------------------------------------------------------
-
- OSErr CreateStandardPartToken( ODFrame* frame, ODPart* part, AEDesc* newToken )
- {
- StandardPartToken spt;
- Environment* ev = somGetGlobalEnvironment();
-
- // refcount the objects since we're saving them
- if (frame)
- frame->Acquire(ev);
- if (part)
- part->Acquire(ev);
-
- spt.fFrame = frame;
- spt.fPart = part;
- return AECreateDesc( kODStandardPartTokenType, &spt, sizeof(spt), newToken );
- }
-
- //------------------------------------------------------------------------------
- // GetDefaultRootFrame
- //------------------------------------------------------------------------------
-
- ODFrame* GetDefaultRootFrame(Environment *ev, ODSession* session)
- {
- ODWindow* odWindow = session->GetWindowState(ev)->AcquireFrontRootWindow(ev);
- ODFrame* rootFrame = odWindow ? odWindow->GetRootFrame(ev) : kODNULL;
- ODReleaseObject(ev, odWindow);
- return rootFrame;
- }
-
- //------------------------------------------------------------------------------
- // ShouldHandleEvent
- //------------------------------------------------------------------------------
-
- pascal ODBoolean ShouldHandleEvent( ODPart* part,
- ODAppleEvent* message,
- ODAppleEvent* reply,
- ODSession* session)
- {
- ODError error = noErr;
- ODOSLToken* oslToken;
- ODDesc* userToken = kODNULL;
- ODPart* contextPart = kODNULL;
- ODPart* realPart = kODNULL;
- ODFrame* contextFrame;
- AEDesc realEvent = {typeNull, kODNULL};
- AEDesc obj = {typeNull, kODNULL};
- Environment* ev = somGetGlobalEnvironment();
- ODNameResolver* resolver = session->GetNameResolver(ev);
- ODBoolean samePart = kODFalse;
- ODBoolean disposeToken = kODFalse;
-
- /*
- This routine shows how to work around the fact that events without a
- direct parameter are sent first to the shell (which you'll never notice),
- then to the root part (which you will notice if your part is also the root)
- and then finally to the destination part specified in the subject attribute.
- In addition, it shows how you can determine the destination frame.
-
- Normally, events are sent to the part containing the direct object.
- This is typically the context of the token which OpenDoc replaces the
- actual object specifier with. So normally, you don't even need to look
- at the direct parameter since you are the object which is handling the
- event. However, in the case where the direct parameter is missing, or
- where the direct parameter is a part reference (i.e. part "Bob",
- part id 65535 or part 1 of part 1 of part 1), the dispatching is a bit
- messy due to the fact that you typically want to send the event to the
- container of the object (i.e. the part who contains the thing) so when
- you refer to a part, the container of that part gets the message. Of
- course, there are some caveats as for who "contains" whom. Most notably,
- a "part id 65535" reference is always "contained" by the root part since
- OpenDoc doesn't walk the tree looking for the actual container. That's
- one of the reasons for this recipe. In addition, it turns out that
- the subject attribute is almost always a part reference, so this
- case turns out to almost always be true when the direct parameter is
- missing or is not an object which OpenDoc can resolve.
-
- Also, this code contains provisions for a change in OpenDoc's
- behavior as of 1.2. Prior to 1.2, OpenDoc does not touch the subject
- attribute while after 1.2 OpenDoc replaces the subject attribute with
- the token it got when resolving the subject, just like it does with the
- direct parameter. This code copes with that scenario.
-
- Finally, this code exposes the details about the standard part token,
- which is not made public in the OpenDoc interfaces. Nevertheless, it
- is necessary and accepted that people will be looking at standard part
- tokens, so this is an acceptable way of dealing with life in the
- SemanticInterface.
- */
-
- TRY
- ODDescToAEDesc(message, &realEvent);
-
- // create an ODOSLToken (which is essentially an ODDesc)
- oslToken = new ODOSLToken;
- THROW_IF_NULL(oslToken);
- oslToken->InitODOSLToken(ev);
-
- // look for and/or at the direct parameter
- error = AEGetKeyDesc(&realEvent, keyDirectObject, typeWildCard, &obj);
- THROW_IF_ERROR( AEDescToODDesc(&obj, oslToken ) );
-
- // if it is missing or not a token then check the subject attribute
- if (error != noErr || !resolver->IsODToken(ev, oslToken)) {
- // there is no direct parameter or it is not an ODToken (i.e. we couldn't resolve it)
- THROW_IF_ERROR( AEGetAttributeDesc(&realEvent, keySubjectAttr, typeWildCard, &obj) );
- if (obj.descriptorType != typeObjectSpecifier) {
- // obj is a token or null
- AEDescToODDesc(&obj, oslToken);
- WASSERT(resolver->IsODToken(ev, oslToken) ||
- oslToken->GetDescType(ev) == typeNull);
- }
- else {
- // the subject was an object so we need to resolve it
-
- // create a wrapper ODObjectSpec (which is just an ODDesc)
- ODObjectSpec* objWrapper = new ODObjectSpec();
- THROW_IF_NULL(objWrapper);
- objWrapper->InitODObjectSpec(ev);
-
- // copy the obj into the ODObjectSpec & dispose of the original
- THROW_IF_ERROR( AEDescToODDesc(&obj, objWrapper ) );
- THROW_IF_ERROR( AEDisposeDesc(&obj) );
-
- // prepare the output ODOSLToken
- oslToken->SetDescType(ev, typeNull);
-
- // resolve the subject attribute & copy the token to obj
- resolver->Resolve(ev, objWrapper, oslToken, kODAppShell);
- THROW_IF_ERROR( ODDescToAEDesc(oslToken, &obj) );
-
- ODDeleteObject(objWrapper);
- disposeToken = kODTrue;
- }
- }
- // At this point both obj & oslToken contain the same data,
- // the token obtained from resolving either the direct parameter
- // or the subject attribute.
- WASSERT(obj.descriptorType == oslToken->GetDescType(ev)); // a cheap check
-
- if (obj.descriptorType != typeNull && obj.dataHandle != kODNULL) {
- // there is an object, so we need to figure out if it is a
- // standard part token and get the part and frame from it or
- // if not, get the context of the token, which should be our part.
- ASSERT(resolver->IsODToken(ev, oslToken), 23);
- userToken = resolver->GetUserToken(ev, oslToken);
- ODDescToAEDesc(userToken, &obj);
- // CanBeStandardPartToken allows developers to make their own tokens
- // which can be coerced into standard part tokens.
- if (CanBeStandardPartToken(&obj)) {
- // A standard part token is merely a part and frame reference, but
- // this routine allows us to hide that info from this code.
- PartFrameFromStandardPartToken(&obj, &contextPart, &contextFrame);
- }
- else {
- // This context was saved during the object resolution and should
- // be the part and frame which contains the object referenced.
- resolver->GetContextFromToken( ev, oslToken, &contextPart, &contextFrame);
- }
- // If we have a frame, then try getting the real part from the part wrapper.
- if (contextFrame) {
- TRY
- realPart = contextPart->GetRealPart(ev);
- samePart = ODObjectsAreEqual(ev, realPart, part);
- contextPart->ReleaseRealPart(ev);
- CATCH_ALL
- WARN("Couldn't get real part, error == %d", ErrorCode());
- ENDTRY
- }
- }
- else {
- // Since we have a null reference, we must be the root frame
- // because without a reference, we can't target anyone else.
- samePart = kODTrue;
- }
-
- // WARN("%sHandle - part = %x, wrapper = %x, frame = %x",
- // samePart ? "" : "Don't ", part, contextPart, contextFrame);
-
- // At this point, if samePart is true, then we're supposed to handle this event.
- CATCH_ALL
- error = ErrorCode();
- ENDTRY
-
- AEDisposeDesc(&realEvent);
- AEDisposeDesc(&realEvent);
- AEDisposeDesc(&obj);
- if (disposeToken)
- resolver->DisposeToken(ev, oslToken);
- else
- ODDeleteObject(oslToken);
- return samePart;
- } // ShouldHandleEvent
-
- /*******************************************************************************
- * CompareDescs
- *
- * Compare two descriptors of the same type. We have a list of known types
- * and valid operations. Invalid types and operations ASSERT and then return
- * kODFalse. All operations are desc1 operation desc2, in that order.
- *
- *******************************************************************************
- */
- ODBoolean
- CompareDescs(const AEDesc *desc1, ODDescType operation, const AEDesc *desc2)
- {
- char *p1, *p2;
- long i, len, len1, len2, theSize;
- Boolean result;
- DescType theKey = typeNull;
- DescType theType, ignoreThis;
- AEDesc coerced = {typeNull, kODNULL};
- AEDesc copy1 = {typeNull, kODNULL};
- AEDesc copy2 = {typeNull, kODNULL};
- AEDesc *myDesc1;
- AEDesc *myDesc2;
- AppleEvent event;
- AEDesc ignoreThese;
- ODBoolean considerCase;
-
- result = kODFalse;
- /* coerce desc2 into same type as desc1 if necessary */
- if (desc1->descriptorType != desc2->descriptorType) {
- TRY
- THROW_IF_ERROR(AECoerceDesc(desc2, desc1->descriptorType, &coerced));
- myDesc2 = &coerced;
- CATCH_ALL
- myDesc2 = kODNULL;
- ENDTRY;
- if (myDesc2 == kODNULL)
- return kODFalse;
- }
- else
- myDesc2 = (AEDesc *)desc2;
- myDesc1 = (AEDesc *)desc1;
- /* either original or coerced copy will be in myDesc2 */
- WASSERT(myDesc1->descriptorType == myDesc2->descriptorType);
- /* Compare lists - recursive comparison iff they are the same length */
- if (myDesc1->descriptorType == typeAEList) {
- THROW_IF_ERROR(AECountItems(myDesc1, &len1));
- THROW_IF_ERROR(AECountItems(myDesc2, &len2));
- switch (operation) {
- case kAEEquals:
- {
- if (len1 != len2)
- return kODFalse;
- for (i = 1; i <= len1; i++) {
- THROW_IF_ERROR(AEGetNthDesc(myDesc1, i, typeWildCard, &theKey, ©1));
- THROW_IF_ERROR(AEGetNthDesc(myDesc2, i, typeWildCard, &theKey, ©2));
- result = CompareDescs(©1, operation, ©2);
- THROW_IF_ERROR(AEDisposeDesc(©1));
- THROW_IF_ERROR(AEDisposeDesc(©2));
- if (!result)
- return kODFalse;
- }
- return kODTrue;
- }
- case kAEContains:
- {
- if (len1 == 0)
- return (len1 == len2);
- if (len2 == 1) {
- WASSERT(desc2->descriptorType != typeAEList);
- for (i = 1; i <= len1; i++) {
- THROW_IF_ERROR(AEGetNthDesc(myDesc1, i, typeWildCard, &theKey, ©1));
- result = CompareDescs(©1, operation, desc2);
- THROW_IF_ERROR(AEDisposeDesc(©1));
- if (result)
- return kODTrue;
- }
- return kODFalse;
- }
- else {
- for (i = 1; i <= len2; i++) {
- THROW_IF_ERROR(AEGetNthDesc(myDesc2, i, typeWildCard, &theKey, ©2));
- result = CompareDescs(myDesc1, operation, ©2);
- THROW_IF_ERROR(AEDisposeDesc(©2));
- if (result)
- return kODTrue;
- }
- return kODFalse;
- }
- }
- default:
- return kODFalse;
- }
- }
-
- /* We assume all data types are contiguous streams of bytes
- * and do byte by byte comparisons in all cases. This
- * results in case sensitive text comparisons, so we'll
- * uppercase copies of both descs.
- */
- if (myDesc1->descriptorType == typeChar) {
- // check the current considering clauses
- considerCase = kODTrue;
- TRY
- THROW_IF_ERROR( AEGetTheCurrentEvent(&event) );
- if (event.dataHandle != kODNULL) {
- THROW_IF_ERROR( AEGetAttributeDesc(&event, enumConsiderations, typeAEList, &ignoreThese) );
- // if list contains kAECase then we should uppercase things
- THROW_IF_ERROR( AECountItems(&ignoreThese, &len) );
- for ( i = 1; i <= len; ++i) {
- THROW_IF_ERROR( AEGetNthPtr(&ignoreThese, i, typeEnumeration, &theKey, &theType,
- &ignoreThis, sizeof(ignoreThis), &theSize) );
- if (ignoreThis == kAECase)
- considerCase = kODFalse;
- }
- }
- CATCH_ALL
- WARN("Unexpected error #%d in CompareDescs", ErrorCode());
- ENDTRY
- if (!considerCase) {
- UppercaseText(*myDesc1->dataHandle, GetHandleSize(myDesc1->dataHandle), smCurrentScript);
- UppercaseText(*myDesc2->dataHandle, GetHandleSize(myDesc2->dataHandle), smCurrentScript);
- }
- }
- switch (operation) {
- case kAEEquals:
- {
- if ((len = GetHandleSize(myDesc1->dataHandle)) !=
- GetHandleSize(myDesc2->dataHandle)) {
- result = kODFalse;
- goto Finish;
- }
- p1 = (char *) *myDesc1->dataHandle;
- p2 = (char *) *myDesc2->dataHandle;
- for (i = 1; i <= len; i++) {
- if (*p1++ != *p2++) {
- result = kODFalse;
- goto Finish;
- }
- }
- result = kODTrue;
- break;
- }
- case kAEGreaterThan:
- case kAEGreaterThanEquals:
- case kAELessThan:
- case kAELessThanEquals:
- {
- len1 = GetHandleSize(myDesc1->dataHandle);
- len2 = GetHandleSize(myDesc2->dataHandle);
- len = len1 < len2 ? len1 : len2;
- p1 = (char *) *myDesc1->dataHandle;
- p2 = (char *) *myDesc2->dataHandle;
- for (i = 1; i <= len; i++) {
- if (*p1 != *p2) {
- switch (operation) {
- case kAEGreaterThan:
- case kAEGreaterThanEquals:
- result = (*p1 > *p2);
- goto Finish;
- case kAELessThan:
- case kAELessThanEquals:
- result = (*p1 < *p2);
- goto Finish;
- }
- }
- p1++;
- p2++;
- }
- switch (operation) {
- case kAEGreaterThan:
- result = (len1 > len2);
- goto Finish;
- case kAEGreaterThanEquals:
- result = (len1 >= len2);
- goto Finish;
- case kAELessThan:
- result = (len1 < len2);
- goto Finish;
- case kAELessThanEquals:
- result = (len1 <= len2);
- goto Finish;
- }
- WASSERT(0);
- }
- case kAEBeginsWith: /* 1 begins with 2 */
- {
- char oldState;
-
- len1 = GetHandleSize(myDesc1->dataHandle);
- len2 = GetHandleSize(myDesc2->dataHandle);
- if (len2 > len1) {
- result = kODFalse;
- goto Finish;
- }
- oldState = HGetState(myDesc2->dataHandle);
- HLock(myDesc2->dataHandle);
- result = Munger(myDesc1->dataHandle, 0, *myDesc2->dataHandle, len2, kODNULL, 0) == 0;
- HSetState(myDesc2->dataHandle, oldState);
- break;
- }
- case kAEEndsWith: /* 1 ends with 2 */
- {
- char oldState;
-
- len1 = GetHandleSize(myDesc1->dataHandle);
- len2 = GetHandleSize(myDesc2->dataHandle);
- if (len2 > len1) {
- result = kODFalse;
- goto Finish;
- }
- oldState = HGetState(myDesc2->dataHandle);
- HLock(myDesc2->dataHandle);
- result = Munger(myDesc1->dataHandle, 0, *myDesc2->dataHandle, len2, kODNULL, 0) == len1 - len2;
- HSetState(myDesc2->dataHandle, oldState);
- break;
- }
- case kAEContains: /* 1 contains 2 */
- {
- char oldState;
-
- len1 = GetHandleSize(myDesc1->dataHandle);
- len2 = GetHandleSize(myDesc2->dataHandle);
- if (len2 > len1) {
- result = kODFalse;
- goto Finish;
- }
- oldState = HGetState(myDesc2->dataHandle);
- HLock(myDesc2->dataHandle);
- result = Munger(myDesc1->dataHandle, 0, *myDesc2->dataHandle, len2, kODNULL, 0) >= 0;
- HSetState(myDesc2->dataHandle, oldState);
- break;
- }
- }
- Finish:
- AEDisposeDesc(&coerced);
- AEDisposeDesc(©1);
- AEDisposeDesc(©2);
- return result;
- }
-
-